// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package interceptor

import (
	"fmt"
	"strings"

	"code.geniusai.org/notebook-manager/pkg/config"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type HttpInterceptor struct {
	httpInterceptorInterface HttpInterceptorInterface
	conf                     *config.Conf
}

func NewHttpInterceptor(httpInterceptorInterface HttpInterceptorInterface, conf *config.Conf) *HttpInterceptor {
	ret := &HttpInterceptor{httpInterceptorInterface, conf}
	return ret
}

// http 请求拦截器
func (h *HttpInterceptor) Interceptor() gin.HandlerFunc {
	return func(c *gin.Context) {

		ID, userID := h.GetParam(c)

		// 返回值代替具体的错误码
		// http响应码用403

		// 判断是否带cookie
		cookie := c.Request.Header.Get("Cookie")
		if len(cookie) == 0 {
			c.AbortWithStatusJSON(200, gin.H{
				"code": "4030001", "msg": "对不起！您没有访问的权限", "success": false, "data": "{}",
			})
			return
		}

		// 判断UserId是否等于cookie userId
		cookieUserId := h.GetUserIdByCookie(cookie)
		if len(userID) != 0 && userID != cookieUserId {
			c.AbortWithStatusJSON(200, gin.H{
				"code": "4030002", "msg": "对不起！您没有访问的权限", "success": false, "data": "{}",
			})
			return
		}

		// 判断notebook ID是否存在
		if len(ID) != 0 && !h.CheckIfIdExist(cookieUserId, ID) {
			c.AbortWithStatusJSON(200, gin.H{
				"code": "4030003", "msg": "对不起！您没有访问的权限", "success": false, "data": "{}",
			})
			return
		}
		// 执行下一个
		c.Next()
	}
}

func (h *HttpInterceptor) GetUserIdByCookie(cookie string) string {

	url := "http://" + h.conf.IstioAuth.Url + ":" + h.conf.IstioAuth.Port
	resp, err := h.httpInterceptorInterface.doReqCookie(url, cookie)
	if err != nil {
		fmt.Printf("doReqCookie failed, err:%v\n\n", err)
		return ""
	}
	defer resp.Body.Close()
	kubeflowUserid := resp.Header.Get(KUBEFLOW_USERID)
	cookieUserId := strings.Replace(kubeflowUserid, HEAD_SUFFIX, "", -1)
	return cookieUserId
}

func (h *HttpInterceptor) CheckIfIdExist(userID string, ID string) bool {
	// 查询该user所有的notebook_id
	ids, err := h.httpInterceptorInterface.GetUserNotebookId(userID)
	if err != nil {
		return false
	}
	set := make(map[string]struct{})
	for _, value := range ids {
		set[value] = struct{}{}
	}
	if _, ok := set[ID]; !ok {
		return false
	}
	return true
}

func (h *HttpInterceptor) GetParam(c *gin.Context) (string, string) {
	paramID := &ParamID{}
	_ = c.ShouldBindBodyWith(paramID, binding.JSON)
	userID := paramID.UserID
	ID := paramID.ID

	if len(userID) == 0 {
		userID = GetUserId(c)
	}

	if len(ID) == 0 {
		ID = GetId(c)
	}
	return ID, userID
}

func GetId(c *gin.Context) string {
	// 路径id
	paramID := &ParamID{}
	_ = c.ShouldBindUri(paramID)

	// 请求参数id
	ID := paramID.ID

	if len(ID) != 0 {
		return ID
	}
	return ""
}

func GetUserId(c *gin.Context) string {
	// 请求路径id
	userID := c.Param("userID")

	if len(userID) != 0 {
		return userID
	}
	return ""
}
